package com.jfinal.server.undertow.hotswap;

import com.jfinal.server.undertow.UndertowKit;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

public class HotSwapClassLoaderBuilder {
    protected final Collection<URL> customClassPathUrls = new LinkedList<>();
    protected ClassLoader parentClassLoader;
    protected HotSwapResolver hotSwapResolver;
    protected boolean devMode = false;

    public Collection<URL> getCustomClassPathUrls() {
        return customClassPathUrls;
    }

    public void addCustomClassPathUrls(URL... urls) {
        customClassPathUrls.addAll(Arrays.asList(urls));
    }

    public void addCustomClassPathUrls(Collection<URL> urls) {
        customClassPathUrls.addAll(urls);
    }

    public ClassLoader getParentClassLoader() {
        return parentClassLoader;
    }

    public void setParentClassLoader(ClassLoader parentClassLoader) {
        this.parentClassLoader = parentClassLoader;
    }

    public HotSwapResolver getHotSwapResolver() {
        return hotSwapResolver;
    }

    public void setHotSwapResolver(HotSwapResolver hotSwapResolver) {
        this.hotSwapResolver = hotSwapResolver;
    }

    public boolean isDevMode() {
        return devMode;
    }

    public void setDevMode(boolean devMode) {
        this.devMode = devMode;
    }

    public ClassLoader build() {
        final URL[] classPathUrls = buildUnionClassPathUrls();

        return new HotSwapClassLoader(classPathUrls, parentClassLoader, hotSwapResolver, devMode);
    }

    protected URL[] buildUnionClassPathUrls() {
        final List<URL> urls = new LinkedList<>();

        urls.addAll(customClassPathUrls);
        urls.addAll(getSystemDefaultClassPath());

        return urls.toArray(new URL[0]);
    }

    protected List<URL> getSystemDefaultClassPath() {
        final List<URL> classPaths = new LinkedList<>();

        UndertowKit.getJavaClassPath().forEach(classPath -> {
            final File file = new File(classPath);
            if (file.exists()) {
                try {
                    classPaths.add(file.toURI().toURL());
                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        return classPaths;
    }

}
